package com.ls.rbac.security;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ls.rbac.entity.User;
import com.ls.rbac.exception.CustomAuthenticationException;
import com.ls.rbac.utils.JwtUtils;
import com.ls.rbac.utils.RedisUtils;
import com.mysql.cj.util.StringUtils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;



import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * created by liusheng
 * on 2025/6/27
 **/
@Component
public class VerifyTokenFilter extends OncePerRequestFilter {

    @Resource
    private LoginFailureHandler loginFailureHandler;

    @Resource
    private CustomUserDetailsService customUserDetailsService;

    @Resource
    private RedisUtils redisUtils;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String uri = request.getRequestURI();
        System.out.println("VerifyTokenFilter: " + uri);
        String[] filterUrls = {
                "/login", "/logout", "/doc.html", "/webjars", "/v3/api-docs", "/favicon.ico",
        };
        for (String url : filterUrls) {
            if (uri.contains(url)) {
                filterChain.doFilter(request, response);
                return;
            }
        }

//        try {
//            validateToken(request, response);
//            // 如果验证通过，继续执行过滤器链
//            filterChain.doFilter(request, response);
//        } catch (AuthenticationException e) {
//            loginFailureHandler.onAuthenticationFailure(request, response, e);
//        }
        filterChain.doFilter(request, response);
    }

    private void validateToken(HttpServletRequest request,
                               HttpServletResponse response) throws IOException {
        String userId = request.getParameter("userId");
        if (userId == null || userId.isEmpty()) {
            throw new CustomAuthenticationException("userId未携带");
        }
        String keyToken = "login:" + userId;
        String valueToken = redisUtils.get(keyToken);
        if (valueToken == null) {
            throw new CustomAuthenticationException("Token不存在或已过期");
        }
        String username = JwtUtils.parseToken(valueToken).getClaim("username").toString();
        String id = JwtUtils.parseToken(valueToken).getClaim("id").toString();
        if (username == null) {
            throw new CustomAuthenticationException("Token中未包含用户名");
        }
        if (!userId.equals(id)) {
            throw new CustomAuthenticationException("userId不匹配");
        }
        // 从 Redis 中获取用户信息
        String userInfoKey = "login:info:" + id;
        String userInfoValue = redisUtils.get(userInfoKey);
        UserDetails details = JSONUtil.toBean(userInfoValue, User.class);
        if (details == null) {
            throw new CustomAuthenticationException("用户信息不存在");
        }
        String permissionKey = "permissions:" + id;
        String permissionsStr = redisUtils.get(permissionKey);
        List<GrantedAuthority> authorities = new ArrayList<>();
        if (StrUtil.isNotBlank(permissionsStr)) {
            List<String> permissionList = StrUtil.split(permissionsStr, ",");
            permissionList.forEach(
                    permission -> authorities.add(new SimpleGrantedAuthority(permission.trim())));
        }
        UsernamePasswordAuthenticationToken authenticationToken = new
                UsernamePasswordAuthenticationToken(
                details, null, authorities);
        //从 request 构建 WebAuthenticationDetails
        authenticationToken.setDetails(
                new WebAuthenticationDetailsSource().buildDetails(request)
        );
        SecurityContextHolder.getContext()
                .setAuthentication(authenticationToken);
    }
}
